package ocbn.remotelab.test_package;

/*
 * PacketProcessorTest.java
 * JMUnit based test
 *
 * Created on 4-Dec-2009, 1:15:46 AM
 */




import ocbn.remotelab.client.*;
import jmunit.framework.cldc10.*;
import ocbn.remotelab.events.ConnStateEvent;
import ocbn.remotelab.events.Event;
import ocbn.remotelab.util.MD5;
import ocbn.remotelab.xml.XMLImport;

/**
 * The jmunit test for PacketProcessor class.
 * @author c8yanche
 */
public class PacketProcessorTest extends TestCase implements EventListener {

    private final String SERVER_ADDR = "Socket://127.0.0.1:7777";
    private final String UNAME = "Tester";
    private final String PUB_KEY = "foo";
    private final String PRIV_KEY = "bar";
    private final int DELAY = 500;
    private Event latestEvent;
    private XMLImport xmlImp = new XMLImport();
    private String sampleEmergePacket = "DATA" +
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<data>" +
                    "<event type=\"MS State\">" +
                        "<id>0x0001</id>" +
                        "<time>Oct 3, 2009 10:12:25 AM</time>" +
                        "<state>failed</state>" +
                        "<source>MS #1</source>" +
                        "<details>" +
                            "<strong>Analyst terminated.</strong><br />" +
                            "Error code: 0x0000036" +
                        "</details>" +
                    "</event>" +
                "</data>";
    private String sampleNormalPacket = "DATA" +
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                "<data>" +
                    "<event type=\"MS State\">" +
                        "<id>0x0002</id>" +
                        "<time>Oct 6, 2009 05:34:49 PM</time>" +
                        "<state>completed</state>" +
                        "<source>MS #2</source>" +
                    "</event>" +
                "</data>";
    private PacketProcessor pp;

    
    public PacketProcessorTest() {
        //The first parameter of inherited constructor is the number of test cases
        super(3,"PacketProcessorTest");
    }            

    public void test(int testNumber) throws Throwable {
        switch (testNumber) {
            case 0:
                testProtocol();
                break;
            case 1:
                testStateReport();
                break;
            case 2:
                testConnectionWithoutServer();
            default:
                break;
        }
    }


    /**
     * Test of process() method, of class PacketProcessor.
     */
    public void testProtocol() throws AssertionFailedException {
        System.out.println("process");
        pp = new PacketProcessor(SERVER_ADDR, UNAME, PRIV_KEY,
                PacketProcessor.BB_DEFAULT);
    
        //Acknoledge test 
        String packet_0 = "ACKN";
        assertNull(pp.process(packet_0));
        
        //Ping test
        String packet_1 = "PING";
        String expected_1 = "ACKN";
        String result_1 = pp.process(packet_1);
        assertEquals(expected_1, result_1);

        //hash test
        String packet_2 = "HKEY"+PUB_KEY;
        String expected_2 = "HASH"+MD5.toMD5(PUB_KEY+PRIV_KEY);
        System.out.println("expected_2 = "+expected_2);
        String result_2 = pp.process(packet_2);
        System.out.println("result_2 = "+result_2);
        assertEquals(expected_2, result_2);

        //auth test
        String packet_3 = "AUTH";
        String result_3 = pp.process(packet_3);
        System.out.println("result_3 = "+result_3);
        assertEquals("ACKN", result_3);

        //data test
        String packet_5 = this.sampleEmergePacket;
        String expected_5 = "ACKN";
        String result_5 = pp.process(packet_5);
        assertEquals(expected_5, result_5);

   

    }

    public void testStateReport() throws AssertionFailedException{
        System.out.println("States");
        pp = new PacketProcessor(SERVER_ADDR, UNAME, PRIV_KEY, 
                PacketProcessor.BB_DEFAULT);
        pp.addListener(this);

        //Normal data
        String packet_0 = this.sampleNormalPacket;
        String expected_0 = xmlImp.importXML(packet_0.substring(4))
                .elementAt(0).toString();
        pp.process(packet_0);
        String result_0 = this.latestEvent.toString();
        assertEquals(expected_0, result_0);

        //Emergency data
        String packet_1 = this.sampleEmergePacket;
        String expected_1 = xmlImp.importXML(packet_1.substring(4))
                .elementAt(0).toString();
        pp.process(packet_1);
        String result_1 = this.latestEvent.toString();
        assertEquals(expected_1, result_1);

        //Success login report
        String packet_2 = "AUTH";
        ConnStateEvent expected_2 = new ConnStateEvent("CONNECTED",
                "Listening for Events from " + SERVER_ADDR + " ...");
        pp.process(packet_2);
        Event result_2 = this.latestEvent;
        assertEquals(expected_2.getDetails(), result_2.getDetails());
        assertEquals(expected_2.getName(), result_2.getName());

        //login error report
        String packet_3 = "LERRtest.";
        ConnStateEvent expected_3 = new ConnStateEvent("DISCONNECTED",
                "Login error: test. Disconnected from "+SERVER_ADDR);
        pp.process(packet_3);
        Event result_3 = this.latestEvent;
        assertEquals(expected_3.getDetails(), result_3.getDetails());
        assertEquals(expected_3.getName(), result_3.getName());

        pp.removeListener(this);  
    }

    public void testConnectionWithoutServer () throws InterruptedException{
        pp = new PacketProcessor(SERVER_ADDR, UNAME, PRIV_KEY,
                PacketProcessor.BB_DEFAULT);

        //test connect
        pp.connect();
        Thread.sleep(DELAY);
        assertTrue(pp.isRunning());
        assertFalse(pp.isAuthed());

        //test disconnect
        pp.terminate();
        Thread.sleep(DELAY);
        assertFalse(pp.isRunning());
        assertFalse(pp.isListening());
        assertFalse(pp.isAuthed());

        //test connection report
        pp.addListener(this);
        pp.connect();
        Thread.sleep(DELAY);
        String expected_0 = "RECONNECTING";
        String result_0 = this.latestEvent.getName();
        assertEquals(expected_0, result_0);
        assertTrue(pp.isRunning());
        assertFalse(pp.isAuthed());
        pp.removeListener(this);
        pp.terminate();
    }

    public void EventReceived(Event e) {
        this.latestEvent = e;
    }
}
